package com.think.cloud.thinkshop.mall.service.shippingtemplates.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.hutool.core.util.ObjectUtil;
import com.think.cloud.thinkshop.mall.controller.admin.shippingtemplates.dto.FreightComputeDTO;
import com.think.cloud.thinkshop.mall.controller.admin.shippingtemplates.dto.ShippingTemplatesDTO;
import com.think.cloud.thinkshop.mall.controller.admin.shippingtemplates.vo.ShippingTemplatesVO;
import com.think.cloud.thinkshop.mall.controller.app.order.vo.AppOrderCommonReqVO;
import com.think.cloud.thinkshop.mall.convert.shippingtemplates.ShippingTemplatesConvert;
import com.think.cloud.thinkshop.mall.domain.Product;
import com.think.cloud.thinkshop.mall.domain.shippingtemplates.ShippingTemplatesProductRef;
import com.think.cloud.thinkshop.mall.domain.shippingtemplates.ShippingTemplatesRegionRef;
import com.think.cloud.thinkshop.mall.service.product.IProductService;
import com.think.cloud.thinkshop.mall.service.shippingtemplates.IShippingTemplatesProductRefService;
import com.think.cloud.thinkshop.mall.service.shippingtemplates.IShippingTemplatesRegionRefService;
import com.think.cloud.thinkshop.mall.service.shippingtemplates.IShippingTemplatesService;
import com.think.common.core.exception.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.think.cloud.thinkshop.mall.mapper.shippingtemplates.ShippingTemplatesMapper;
import com.think.cloud.thinkshop.mall.domain.shippingtemplates.ShippingTemplates;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.transaction.annotation.Transactional;

/**
 * 物流方案Service业务层处理
 *
 * @author zkthink
 * @date 2024-05-15
 */
@Service
public class ShippingTemplatesServiceImpl implements IShippingTemplatesService {
    @Autowired
    private ShippingTemplatesMapper shippingTemplatesMapper;
    @Autowired
    private IShippingTemplatesProductRefService productRefService;
    @Autowired
    private IShippingTemplatesRegionRefService regionRefService;
    @Autowired
    private IProductService productService;

    /**
     * 查询物流方案
     *
     * @param id 物流方案主键
     * @return 物流方案
     */
    @Override
    public ShippingTemplatesVO selectShippingTemplatesById(Long id) {
        ShippingTemplates shippingTemplates = shippingTemplatesMapper.selectById(id);
        ShippingTemplatesVO dto = ShippingTemplatesConvert.INSTANCE.convert2VO(shippingTemplates);

        dto.setProductIds(productRefService.selectProductIdsByTemplateId(id));
        dto.setRegionIds(regionRefService.selectRegionIdsByTemplateId(id));
        List<Product> products = new ArrayList<>();
        if(ObjectUtil.isNotEmpty(dto.getProductIds())){
            products = productService.selectProductByProductIds(dto.getProductIds());
            // 获取商品第一张图片作为主图
            products.forEach(res -> res.setImage(res.getImage().split(",")[0]));
        }
        dto.setProductList(products);
        return dto;
    }

    /**
     * 查询物流方案列表
     *
     * @param shippingTemplates 物流方案
     * @return 物流方案
     */
    @Override
    public List<ShippingTemplates> selectShippingTemplatesList(ShippingTemplates shippingTemplates) {
        return shippingTemplatesMapper.selectList(new LambdaQueryWrapper<>());
    }

    /**
     * 新增物流方案
     *
     * @param shippingTemplates 物流方案
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertShippingTemplates(ShippingTemplatesDTO shippingTemplates) {
        ShippingTemplates templates1 = getShippingTemplatesByName(shippingTemplates.getName());
        if (templates1 != null) {
            throw new ServiceException("方案名称重复");
        }
        //查询当前区域是否已经设置模版
        List<String> regionIds = shippingTemplates.getRegionIds();
        if (regionIds != null && !regionIds.isEmpty()) {
            List<ShippingTemplatesRegionRef> regionRefList = regionRefService.selectByRegionIds(regionIds);
            Map<String, ShippingTemplatesRegionRef> regionRefMap = regionRefList.stream().collect(Collectors.toMap(ShippingTemplatesRegionRef::getRegionId, Function.identity()));
            for (String regionId : regionIds) {
                ShippingTemplatesRegionRef regionRef = regionRefMap.get(regionId);
                if (regionRef != null) {
                    throw new ServiceException("区域已经设置模版");
                }
            }
        }
        ShippingTemplates templates = ShippingTemplatesConvert.INSTANCE.convert(shippingTemplates);
        int res = shippingTemplatesMapper.insert(templates);
        if (res > 0) {
            //新增商品关联
            productRefService.saveBatch(templates.getId(), shippingTemplates.getProductIds(), true);
            //新增地区关联
            regionRefService.saveBatch(templates.getId(), shippingTemplates.getRegionIds(), true);
        }
        return res;
    }

    /**
     * 修改物流方案
     *
     * @param shippingTemplates 物流方案
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateShippingTemplates(ShippingTemplatesDTO shippingTemplates) {
        ShippingTemplates templates1 = getShippingTemplatesByName(shippingTemplates.getName());
        if (templates1 != null && !templates1.getId().equals(shippingTemplates.getId())) {
            throw new ServiceException("方案名称重复");
        }
        //查询当前区域是否已经设置模版
        List<String> regionIds = shippingTemplates.getRegionIds();
        if (regionIds != null && !regionIds.isEmpty()) {
            List<ShippingTemplatesRegionRef> regionRefList = regionRefService.selectByRegionIds(regionIds);
            Map<String, ShippingTemplatesRegionRef> regionRefMap = regionRefList.stream().collect(Collectors.toMap(ShippingTemplatesRegionRef::getRegionId, Function.identity()));
            for (String regionId : regionIds) {
                ShippingTemplatesRegionRef regionRef = regionRefMap.get(regionId);
                if (regionRef != null && !regionRef.getTemplateId().equals(shippingTemplates.getId())) {
                    throw new ServiceException("区域已经设置模版");
                }
            }
        }
        ShippingTemplates templates = ShippingTemplatesConvert.INSTANCE.convert(shippingTemplates);
        int res = shippingTemplatesMapper.updateById(templates);
        if (res > 0) {
            //新增商品关联
            productRefService.saveBatch(templates.getId(), shippingTemplates.getProductIds(), false);
            //新增地区关联
            regionRefService.saveBatch(templates.getId(), shippingTemplates.getRegionIds(), false);
        }
        return res;
    }

    private ShippingTemplates getDefault() {
        return shippingTemplatesMapper.selectOne(new LambdaQueryWrapper<ShippingTemplates>().eq(ShippingTemplates::getIsDefault, true));
    }

    private ShippingTemplates getShippingTemplatesByName(String name) {
        return shippingTemplatesMapper.selectOne(new LambdaQueryWrapper<ShippingTemplates>().eq(ShippingTemplates::getName, name));
    }

    /**
     * 批量删除物流方案信息
     *
     * @param ids 主键集合
     * @return 结果
     */
    @Override
    public int batchDelete(List<Long> ids) {
        return shippingTemplatesMapper.deleteBatchIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteById(Long id) {
        //判断是否为默认方案
        if (shippingTemplatesMapper.selectById(id).getIsDefault()) {
            throw new ServiceException("默认方案不能删除");
        }
        int res = shippingTemplatesMapper.deleteById(id);
        //删除关联信息
        if (res > 0) {
            productRefService.deleteByTemplateId(id);
            regionRefService.deleteByTemplateId(id);
        }
        return res;
    }

    @Override
    public BigDecimal calculatePrice(FreightComputeDTO dto, AppOrderCommonReqVO vo) {
        //校验此地址是否有效 1.地址是否有物流方案 2.选择商品是否在同一方案中
        boolean addressValid = true;
        BigDecimal price = BigDecimal.ZERO;

        //根据地区查询对应模版
        ShippingTemplatesRegionRef shippingTemplatesRegionRef = regionRefService.selectByRegionId(dto.getRegionId());
        if (Objects.isNull(shippingTemplatesRegionRef)) {
            addressValid = false;
            vo.setAddressValid(addressValid);
            return price;
        }
        List<Long> productIds = dto.getProductIds();
        //判断选择商品是否在同一方案中
        if (productIds != null && !productIds.isEmpty()) {
            List<ShippingTemplatesProductRef> productRefList = productRefService.selectByProductIds(productIds);
            boolean isNotSame = productRefList.stream().map(ShippingTemplatesProductRef::getTemplateId).distinct().count() > 1;
            if (isNotSame) {
                addressValid = false;
                vo.setAddressValid(addressValid);
                return price;
            }
        }
        vo.setAddressValid(addressValid);
        ShippingTemplates templates = shippingTemplatesMapper.selectById(shippingTemplatesRegionRef.getTemplateId());
        // 计算运费
        return ShippingCalculator.calculate(dto.getOrderAmount(), productIds.size(), dto.getWight(), templates);
    }
}
